Simple REST API in Go (Gin) for vulnerability summaries based on NIST NVD data, plus remediation tracking for IT assets.
- Fetches vulnerabilities from NVD (CVE 2.0 API).
- Stores normalized vulnerability data in PostgreSQL.
- Provides severity summaries.
- Tracks remediated CVEs per asset.
- Calculates uncorrected summary (vulnerabilities not remediated in any asset).
- Go 1.24
- Gin
- PostgreSQL 16
- Docker + Docker Compose
main.go: app bootstrap and route wiringconfig/: environment and secret-based config loadingdatabase/: PostgreSQL connection and migrationshandlers/: HTTP handlersservices/: NVD client and business logicrepositories/: DB access layermodels/: domain/request/response models
- In GCP, secrets are managed with Secret Manager (
db-password,nvd-api-key,iap-client-secret,database-url). - Terraform reads sensitive values from Secret Manager and avoids plaintext secrets in
terraform.tfvars. - Local
.envfiles are ignored by git.
- Docker Desktop (or Docker Engine + Compose)
Use .env (based on .env.example):
POSTGRES_DB=security_api
POSTGRES_USER=postgres
POSTGRES_PASSWORD=__SET_SECURE_VALUE__
NVD_API_KEY=__SET_OPTIONAL_FOR_LOCAL_DOCKER__
HTTP_TIMEOUT_SECONDS=20
NVD_RESULTS_PER_PAGE=500
NVD_MAX_PAGES=3docker compose up -dCheck services:
docker compose psStop:
docker compose downGET /vulnerabilities/summary
- Returns severity summary from DB.
- If DB is empty, service performs initial sync from NVD.
POST /assets/:asset_id/vulnerabilities
- Registers remediated CVEs for an asset.
- Body:
{
"cves": ["CVE-2023-1234", "CVE-2022-9999"]
}GET /vulnerabilities/summary/uncorrected
- Returns severity summary excluding CVEs already remediated.
Additional endpoint:
POST /vulnerabilities/sync(manual sync trigger from NVD)
curl http://localhost:8080/vulnerabilities/summary
curl http://localhost:8080/vulnerabilities/summary/uncorrected
curl -X POST http://localhost:8080/assets/server-01/vulnerabilities \
-H "Content-Type: application/json" \
-d '{"cves":["CVE-2023-1234"]}'- Add a new Secret Manager version for
nvd-api-key. - Re-run Terraform apply (or redeploy Cloud Run) to pick up latest secret version.
Local Docker only:
- Update
NVD_API_KEYin your local.env. - Recreate API container:
docker compose up -d --force-recreate api- No DB preloading at startup: only schema migration runs on boot.
- Data sync is explicit (
/vulnerabilities/sync) or lazy on first summary call.
Terraform infrastructure for this architecture is available at infra/terraform:
- IAP (SSO + MFA) in front of HTTPS Load Balancer
- Cloud Run (Dockerized Gin API)
- Cloud SQL (PostgreSQL)
- Secret Manager
- Pub/Sub + Cloud Scheduler
- Cloud Armor (WAF)
Quick start:
cp infra/terraform/terraform.tfvars.example infra/terraform/terraform.tfvars- Create required Secret Manager secrets (
db-password,nvd-api-key,iap-client-secret) - Edit non-secret values in
infra/terraform/terraform.tfvars cd infra/terraformterraform init && terraform apply